package com.wjj.sixinone.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wjj.sixinone.common.enums.ExceptionEnum;
import com.wjj.sixinone.common.enums.StatusEnum;
import com.wjj.sixinone.common.exception.GlobalException;
import com.wjj.sixinone.common.pojo.dto.BedDTO;
import com.wjj.sixinone.common.pojo.dto.CapacityDTO;
import com.wjj.sixinone.common.pojo.entity.Bed;
import com.wjj.sixinone.common.pojo.entity.Room;
import com.wjj.sixinone.common.pojo.excel.BedExcel;
import com.wjj.sixinone.common.pojo.vo.BedForm;
import com.wjj.sixinone.common.pojo.vo.BedVO;
import com.wjj.sixinone.common.util.Result;
import com.wjj.sixinone.handler.ExcelExportHandle;
import com.wjj.sixinone.mapper.BedMapper;
import com.wjj.sixinone.mapper.RoomMapper;
import com.wjj.sixinone.service.BedService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import lombok.val;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 小王不秃头
 * @since 2024-07-22
 */
@Service
public class BedServiceImpl extends ServiceImpl<BedMapper, Bed> implements BedService {

    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private ExcelExportHandle excelHandler;

    @Override
    public Result listRoomNo() {
        List<Room> beds = roomMapper.selectList(new LambdaQueryWrapper<Room>().select(Room::getRoomNo));
        if (beds == null) {
            throw new GlobalException(ExceptionEnum.SELECT_ERROR);
        }

        return Result.ok().put("data",beds);
    }

    @Override

    public Result selectBedByLimit(BedVO bedVO) {
        Integer page = bedVO.getPage();
        Integer limit = bedVO.getLimit();
        int index = (page - 1) * limit;
        BedDTO bedDTO = new BedDTO();
        BeanUtils.copyProperties(bedVO,bedDTO);
        bedDTO.setIndex(index);
        List<Bed> beds = bedMapper.selectRoomByLimit(bedDTO);

       Integer count= bedMapper.count(bedDTO);

        return Result.ok().put("data",beds).put("count",count);
    }

    @Override
    @Transactional

    public Result addBed(BedForm bedForm) {
        String roomNo = bedForm.getRoomNo();

        Room room = getRoom(roomNo);
        //容量
        Integer roomCapacity = room.getRoomCapacity();

        //入住人数
            Integer number =   bedMapper.selectBedCount(roomNo);
            List<String>bedNos = bedMapper.selectBedNo(roomNo);
        if (number >= roomCapacity) {
            throw new GlobalException(ExceptionEnum.BED_FULL);
        }
        //检查床位是否冲突
        if(number!=0) {
            for (String s : bedNos) {
                if (s.equals(bedForm.getBedNo())) {
                    throw new GlobalException(ExceptionEnum.BED_EXIST);
                }
            }
        }

        Bed bed = new Bed();
        BeanUtils.copyProperties(bedForm,bed);
        if (bedMapper.insert(bed) < 0) {
            throw new GlobalException(ExceptionEnum.INSERT_ERROR);
        }

        return Result.ok();
    }

    /**
     * 根据ID更新床位信息。
     *
     * @param bedForm 包含待更新床位信息的表单。
     * @return 返回操作结果，成功则为OK。
     * @throws GlobalException 如果更新失败或床位已满，则抛出全局异常。
     */
    @Override
    @Transactional

    public Result updateBedById(BedForm bedForm) {
        // 获取房间号
        String roomNo = bedForm.getRoomNo();
        // 根据房间号获取房间信息
        Room room = getRoom(roomNo);

        // 获取房间ID和床位表单中的ID
        int id = room.getId();
        int id1 = bedForm.getId();
        // 如果房间ID和床位ID不相同
        // 不是同一个房间 床位号可以相等
        if (id != id1) {

                Integer number=bedMapper.selectBedCount(roomNo);
               List<String> bedNos = bedMapper.selectBedNo(roomNo);

            // 检查房间是否已满
            if (room.getRoomCapacity() <= number) {
                throw new GlobalException(ExceptionEnum.BED_FULL);
            }
            //检查床位是否冲突

            if(number !=0) {
                for (String s : bedNos) {
                    if (s.equals(bedForm.getBedNo())) {
                        throw new GlobalException(ExceptionEnum.BED_EXIST);
                    }
                }
            }

            // 创建新的Bed对象并复制表单属性

            Bed bed = new Bed();
            BeanUtils.copyProperties(bedForm, bed);
            // 尝试更新床位信息，如果更新失败则抛出异常
            if (bedMapper.updateById(bed) < 0) {
                throw new GlobalException(ExceptionEnum.UPDATE_ERROR);
            }
        }
        // 如果房间ID和床位ID相同
        //在同一个房间,床位不能相同
        else {
            // 创建新的Bed对象
            Bed bed = new Bed();
            // 获取待更新的床位号
            String bedNo = bedForm.getBedNo();
            // 查询房间中是否有相同床位号的床位
            Bed bed1 = bedMapper.selectOne(new LambdaQueryWrapper<Bed>().select(Bed::getId).eq(Bed::getBedNo, bedNo));
            if (bed1 != null && !bed1.getId().equals(bedForm.getId())) {
                throw new GlobalException(ExceptionEnum.BED_EXIST);
            }

            BeanUtils.copyProperties(bedForm, bed);
            // 尝试更新床位信息，如果更新失败则抛出异常
            if (bedMapper.updateById(bed) < 0) {
                throw new GlobalException(ExceptionEnum.UPDATE_ERROR);
            }
        }
        // 返回操作成功的结果
        return Result.ok();
    }

    @Override
    public Result deleteBedById(Map<String, Integer> map) {
        if (bedMapper.deleteById(map.get("id")) < 0) {
            throw new GlobalException(ExceptionEnum.DELETE_ERROR);
        }
        return Result.ok();
    }

    @Override
    public void uploadExcel(HttpServletResponse httpServletResponse) {
        List<Bed> beds = bedMapper.selectList(null);
        List<BedExcel> bedExcels =new ArrayList<>();
        beds.forEach(bed -> {
            BedExcel bedExcel = new BedExcel();
            BeanUtils.copyProperties(bed,bedExcel);
            bedExcels.add(bedExcel);
        });
        excelHandler.export(httpServletResponse,"床位信息",bedExcels, BedExcel.class);
    }

    @Override
    public Result listBedNoByRoomNo(String roomNo) {
        //搜索当前房间，空闲床位
        List<String> bedNos = bedMapper.selectBedGoodNo(roomNo, StatusEnum.NOT_USE.getMessage());
        return Result.ok().put("data",bedNos);
    }

    private Room getRoom(String roomNo) {
        Room room = roomMapper.selectOne(new LambdaQueryWrapper<Room>().select(Room::getRoomCapacity,Room::getId).eq(Room::getRoomNo, roomNo));
        if (room == null) {
            throw new GlobalException(ExceptionEnum.SELECT_ERROR);
        }
        return room;
    }
}
